package com.xxxx.server.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xxxx.server.config.security.component.JwtTokenUtils;
import com.xxxx.server.mapper.AdminMapper;
import com.xxxx.server.mapper.AuthorityMapper;
import com.xxxx.server.mapper.UserauthorityMapper;
import com.xxxx.server.pojo.*;
import com.xxxx.server.service.IAdminService;
import com.xxxx.server.service.IVisualdataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author LT
 * @since 2022-02-27
 */
@Service
public class AdminServiceImpl extends ServiceImpl<AdminMapper, Admin> implements IAdminService {

    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private JwtTokenUtils jwtTokenUtils;
    //将配置文件中存的值取过来
    @Value("${jwt.tokenHead}")
    private String tokenHead;

    @Autowired
    private AdminMapper adminMapper;

    @Autowired
    private AuthorityMapper authorityMapper;

    @Autowired
    private UserauthorityMapper userauthorityMapper;
    //密码加密
    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;
    @Autowired
    private IVisualdataService visualdataService;

    /**
     * 实现方法
     * 登录后返回token
     *
     * @param username
     * @param password
     * @param captcha
     * @param request
     * @return
     */
    @Override
    public RespBean login(String username, String password, String captcha, HttpServletRequest request) {
        /**每次登陆时自动同步数据,如果今天已经同步过数据则更新数据
         *
         */
        //1.查询统计数据
        Visualdata visualdata=new Visualdata();
        LocalDate today= LocalDate.now();
       Integer n=   visualdataService.IsRepeat(today);
        System.out.println("n的值为:"+n);
       //数据库没有今天的数据则插入今天的数据
        if(n==null)
        {
            visualdata.setId(0);
            visualdata.setTotalUsers(visualdataService.getTodayUsers());
            visualdata.setTotalLectures(visualdataService.getTodayLectures());
            visualdata.setTotalReverse(visualdataService.getTodayReverses());
            visualdata.setRecordDate(today);
            visualdataService.save(visualdata);
        }
        else
        {

           Integer visualdataId=visualdataService.getVisualdataIdByTodayId(today);
            visualdata.setId(visualdataId);
            visualdata.setTotalUsers(visualdataService.getTodayUsers());
            visualdata.setTotalLectures(visualdataService.getTodayLectures());
            visualdata.setTotalReverse(visualdataService.getTodayReverses());
            visualdata.setRecordDate(today);
            visualdataService.updateById(visualdata);
        }


        //获取验证码
        String defaultKaptcha = (String) request.getSession().getAttribute("captcha");
        System.out.println("登录验证的验证码：" + captcha);
        //忽略大小写进行比较
        if (StringUtils.isEmpty(captcha) || !defaultKaptcha.equalsIgnoreCase(captcha)) {
            return RespBean.error("验证码不正确，请重新输入！");
        }

        //获取userDetails
        //登陆
        UserDetails userDetails = userDetailsService.loadUserByUsername(username);
        System.out.println(userDetails);

        boolean f = bCryptPasswordEncoder.matches(password, userDetails.getPassword());
        System.out.println(f);
        System.out.println(!f);
        System.out.println(userDetails.toString().length()==0);

        if(!f){
            return RespBean.error("用户名或者密码不正确");
        }
        //判断账号是否被禁用
        if (!userDetails.isEnabled()) {
            return RespBean.error("账号被禁用,请联系管理员");
        }

        // 更新security登录用户对象
        // null 的位置本来该放密码，但是一般是不放密码的
        // userDetails.getAuthorities() 是权限列表
        System.out.println(userDetails.getAuthorities());
        UsernamePasswordAuthenticationToken authentication =
                new UsernamePasswordAuthenticationToken(userDetails, userDetails.getPassword(),
                        userDetails.getAuthorities());
        // 放在security全局里面
        SecurityContextHolder.getContext().setAuthentication(authentication);


        // 到这里说明没问题 就让他拿到令牌
        String token = jwtTokenUtils.generateToken(userDetails);
        Map<String, String> tokenMap = new HashMap<>();
        tokenMap.put("token", token);
        tokenMap.put("tokenHead", tokenHead);//返回头部信息

        // 登录成功之后返回一个token给前端
        return RespBean.success("登录成功", tokenMap);//tokenMap中有 username，new Date（），tokenHead
    }


    /**
     * 根据用户名获取用户方法实现
     *
     * @param username
     * @return
     */
    @Override
    public Admin getAdminByUserName(String username) {
        //().().() 链式编程
        //使用MybatisPlus的单个查询方法，selectOne 用.eq 比较方法在匹配查询条件
        return adminMapper.selectOne(new QueryWrapper<Admin>().eq("username", username)
                .eq("enabled", true));
    }

    /**
     * 方法实现
     * 根据用户id查询权限列表
     *
     * @param adminId
     * @return
     */
    @Override
    public List<Authority> getAuthorityByAdminId(Integer adminId) {

        return authorityMapper.getAuthorityByAdminId(adminId);
    }

    /**
     * 通过关键字获取用户 实现 传入当前登录用户id 查询时剔除登录用户的信息
     *
     * @param keywords
     * @return
     */
    @Override
    public List<Admin> getAllUsersByKeywords(String keywords) {
        return adminMapper.getAllUsersByKeywords(((Admin) SecurityContextHolder.
                getContext().getAuthentication().getPrincipal()).getId(), keywords);
        //((Admin)SecurityContextHolder.
        //                getContext().getAuthentication().getPrincipal())获取当前登录用户id
    }

    /**
     * 更新用户权限
     *
     * @param userId
     * @param authorityIds
     * @return
     */
    @Override
    public RespBean addAdminAuthority(Integer userId, List<Integer> authorityIds) {
        //先删除用户权限,进行添加
        if(authorityIds.size()!=0)
        {

            userauthorityMapper.delete(new QueryWrapper<Userauthority>().eq("userId", userId));
            Integer result = userauthorityMapper.addAdminAuthority(userId, authorityIds);
            if (authorityIds.size() == result) {
                return RespBean.success("更新成功!");
            }
            return RespBean.error("更新失败!");
        }
        else
        {
            userauthorityMapper.delete(new QueryWrapper<Userauthority>().eq("userId", userId));
                return RespBean.success("更新成功!");

        }

    }






    @Override
    public boolean addAdmin(Admin admin) {
        return adminMapper.addAdmin(admin);
    }

    @Override
    public Integer getDataByAddUserName(String addUserName) {
        return adminMapper.getDataByAddUserName(addUserName);
    }




}
